const fs = require('fs');
const url = require('url');
const querystring = require('querystring');
const Buffer = require('buffer').Buffer;

async function main() {
    const inputFile = '/home/caoyangjie/clash/clash-for-linux/temp/proxy.txt';
    const outputFile = '/home/caoyangjie/clash/clash-for-linux/temp/proxies.yaml';
    const templateFile = '/home/caoyangjie/clash/clash-for-linux/temp/template_config.yaml';
    const templateRuleFile = '/home/caoyangjie/clash/clash-for-linux/temp/rules.txt';

    const groupNames = [];
    
    try {
        // 读取模板文件
        const templateContent = fs.readFileSync(templateFile, 'utf-8');
        const ruleContent = fs.readFileSync(templateRuleFile, 'utf-8');
        const proxies = [];

        // 处理代理配置
        const lines = fs.readFileSync(inputFile, 'utf-8').split('\n');
        for (const line of lines) {
            const trimmed = line.trim();
            if (!trimmed) continue;

            try {
                if (trimmed.startsWith('trojan://')) {
                    proxies.push(convertTrojan(trimmed, groupNames));
                } else if (trimmed.startsWith('vmess://')) {
                    proxies.push(convertVmess(trimmed, groupNames));
                } else if (trimmed.startsWith('ss://')) {
                    proxies.push(convertSS(trimmed, groupNames));
                } else {
                    console.log('Unsupported format:', trimmed);
                }
            } catch (e) {
                console.error('Error processing line:', e.message);
            }
        }

        // 生成最终 YAML
        const output = [
            templateContent,
            '\nproxies:',
            ...proxies,
            '\nproxy-groups:',
            '  - name: Proxy',
            '    type: select',
            '    proxies:',
            ...groupNames.map(name => `      - "${name}"`),
            ruleContent
        ].join('\n');

        fs.writeFileSync(outputFile, output);
        console.log('Configuration generated successfully');

    } catch (error) {
        console.error('Error:', error);
    }
}

function convertTrojan(trojanUrl, groupNames) {
    try {
        const parsed = new url.URL(trojanUrl);
        const params = querystring.parse(parsed.searchParams.toString());
        
        const config = {
            name: decodeURIComponent(parsed.hash.slice(1)),
            type: 'trojan',
            server: parsed.hostname,
            port: parsed.port || 443,
            password: parsed.username,
            sni: params.sni || parsed.hostname,
            allowInsecure: params.allowInsecure === '1' ? false : true,
            udp: true
        };

        groupNames.push(config.name);
        return toYaml(config);
    } catch (error) {
        throw new Error(`Invalid Trojan URL: ${error.message}`);
    }
}

function convertVmess(vmessUrl, groupNames) {
    try {
        const base64 = vmessUrl.slice(8).replace(/-/g, '+').replace(/_/g, '/');
        const decoded = Buffer.from(base64, 'base64').toString();
        const vmess = JSON.parse(decoded);

        const config = {
            name: vmess.ps,
            type: 'vmess',
            server: vmess.add,
            port: vmess.port,
            uuid: vmess.id.replace(/-/g, ''),
            alterId: 0,
            cipher: 'auto',
            network: vmess.net || 'tcp',
            tls: vmess.tls === 'tls'
        };

        if (vmess.net === 'ws') {
            config.wsOpts = {
                path: vmess.path || '/',
                headers: { Host: vmess.host || '' }
            };
        }

        if (config.tls) {
            config.servername = vmess.host || vmess.add;
        }

        groupNames.push(config.name);
        return toYaml(config);
    } catch (error) {
        throw new Error(`Invalid VMess URL: ${error.message}`);
    }
}

function convertSS(ssUrl, groupNames) {
    try {
        const parts = ssUrl.slice(5).split('@');
        const userinfo = Buffer.from(parts[0], 'base64').toString();
        const [method, password] = userinfo.split(':');
        
        const serverPart = parts[1].split('#')[0];
        const [server, port] = serverPart.split(':');
        const name = decodeURIComponent(parts[1].split('#')[1] || server);

        const config = {
            name,
            type: 'ss',
            server,
            port: parseInt(port),
            cipher: method,
            password
        };

        groupNames.push(config.name);
        return toYaml(config);
    } catch (error) {
        throw new Error(`Invalid Shadowsocks URL: ${error.message}`);
    }
}

function toYaml(config) {
    const lines = ['  - name: ' + JSON.stringify(config.name)];
    for (const [key, value] of Object.entries(config)) {
        if (key === 'name') continue;
        
        if (typeof value === 'object') {
            lines.push(`    ${key}:`);
            for (const [subKey, subValue] of Object.entries(value)) {
                lines.push(`      ${subKey}: ${JSON.stringify(subValue)}`);
            }
        } else {
            lines.push(`    ${key}: ${JSON.stringify(value)}`);
        }
    }
    return lines.join('\n');
}

main().catch(console.error);

